package com.xiaoxu.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.xiaoxu.cart.service.CartService;
import com.xiaoxu.product.FeignProductSku;
import com.xiaoxu.spzx.model.entity.h5.CartInfo;
import com.xiaoxu.spzx.model.entity.product.ProductSku;
import com.xiaoxu.spzx.utils.AuthContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate<String , String> redisTemplate;

    //注册远程服务端口
    @Autowired
    private FeignProductSku feignProductSku;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
// 1.从当前线程中获取用户信息
        Long userId = AuthContextUtil.getUserInfo().getId();
        //构建hash类类型key名称
        String cartKey = this.getCartKey(userId);
        //购物车放到Redis中
        CartInfo cartInfo = null ;
        ///redis数据类型: Redis hash key cartKey, field:skuId, value:cartInfo
        /// user:cart 001 sku001 ....
        //hash类型存储商品信息
        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));

        if (cartInfoObj != null) {
            //购物车存在添加商品,把商品数量添加 cartInfoObj (Object) --- cartInfo(CartInfo)
            cartInfo = JSON.parseObject(cartInfoObj.toString(), CartInfo.class);
            //将数量加1
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //将其他信息跟新
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());

        }else{
            //远程调用 : nacos +　openFeign 实现 根据skuId 获取商品sku信息
            //购物车不存在,直接将商品添加
            // 当购物车中没用该商品的时候，则直接添加到购物车！
            cartInfo = new CartInfo();
            ProductSku productSku = feignProductSku.getSkuById(skuId);
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }
        //将商品数据保存在redis 数据库中
        redisTemplate.opsForHash().put(
                cartKey,
                String.valueOf(skuId),
                JSON.toJSONString(cartInfo)
        );
    }
    //查询购物车 列表的方法
    @Override
    public List<CartInfo> cartList() {
        //从当前线程中获取用户信息
        Long id = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(id);
        //根据key来获取Hash类型的value值
        List<Object> valuesList = redisTemplate.opsForHash().values(cartKey);


        //将Object类型转换为最终的cartInfo类型
        if (!CollectionUtils.isEmpty(valuesList)){
            List<CartInfo> infoList = valuesList.stream()
                    .map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return infoList ;
        }

        //如果购物车为空 []
        return new ArrayList<>();
    }
    //删除购物车
    @Override
    public void deleteCart(Long skuId) {
    //获取当前用户信息
        Long id = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(id);
        //删除redis数据库的Hash
        redisTemplate.opsForHash().delete(cartKey,String.valueOf(skuId));
    }
    //修改购物车选项
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //获取当前用户信息
        Long id = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(id);
        //获取购物车列表
        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));

        if (hasKey){
            String cartInfoString = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId)).toString();

            //更新value的状态
            CartInfo cartInfo = JSON.parseObject(cartInfoString, CartInfo.class);

            cartInfo.setIsChecked(isChecked);

            //放回redis的hash类型
            redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId),JSON.toJSONString(cartInfo));

        }

    }
    //更新全部选中
    @Override
    public void allCheckCart(Integer isChecked) {
        // 获取当前登录的用户数据
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        // 获取所有的购物项数据
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);


        if (!CollectionUtils.isEmpty(objectList)){
            List<CartInfo> cartInfoList = objectList.stream().map(object ->
                            JSON.parseObject(object.toString(), CartInfo.class))
                    .collect(Collectors.toList());

            //把每个商品isChecked进行更新
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                redisTemplate.opsForHash().put(cartKey,String.valueOf(cartInfo.getSkuId()
                ),JSON.toJSONString(cartInfo));
            });
        }
    }
    //清空购物车
    @Override
    public void clearCart() {
        //获取当前用户信息
        Long id = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(id);
        //删除redis数据库的Hash
        redisTemplate.delete(cartKey);
    }
    //查询购物车选中商品
    @Override
    public List<CartInfo> getAllCkecked() {
        //获取当前得登录用户
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(userId);

        //查询redis hash类型得数据库
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);

        //转换成cartInfo 类型
        if (!CollectionUtils.isEmpty(objectList)){
            List<CartInfo> cartInfoList = objectList.stream().
                    map(objectInfo -> JSON.parseObject(objectInfo.toString(), CartInfo.class
            )).filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
            return cartInfoList;
        }
        return new ArrayList<>();
    }

    //构建hash类类型key名称
    private String getCartKey(Long userId) {
        //定义key user:cart:userId
        return "user:cart:" + userId;
    }
}
